/**
 * 弹球游戏主类
 * @description 管理游戏的核心逻辑，包括球、球拍、碰撞检测等
 */
export class PongGame {
    constructor(canvas, ctx) {
        this.canvas = canvas;
        this.ctx = ctx;

        // 游戏配置
        this.config = {
            paddleWidth: 15,
            paddleHeight: 100,
            ballSize: 10,
            ballSpeed: 5,
            paddleSpeed: 8,
            maxScore: 11,
            centerLineWidth: 2,
            centerLineDash: 10
        };

        // 游戏状态
        this.isRunning = false;
        this.isPaused = false;
        this.player1Score = 0;
        this.player2Score = 0;
        this.roundCount = 1;
        this.ballSpeed = this.config.ballSpeed;

        // 初始化游戏对象
        this.initGameObjects();

        // 绑定事件
        this.bindEvents();
    }

    /**
     * 初始化游戏对象
     */
    initGameObjects() {
        const canvasWidth = this.canvas.width;
        const canvasHeight = this.canvas.height;

        // 初始化球拍
        this.paddle1 = {
            x: 50,
            y: canvasHeight / 2 - this.config.paddleHeight / 2,
            width: this.config.paddleWidth,
            height: this.config.paddleHeight,
            speed: 0,
            color: '#4CAF50'
        };

        this.paddle2 = {
            x: canvasWidth - 50 - this.config.paddleWidth,
            y: canvasHeight / 2 - this.config.paddleHeight / 2,
            width: this.config.paddleWidth,
            height: this.config.paddleHeight,
            speed: 0,
            color: '#2196F3'
        };

        // 初始化球
        this.ball = {
            x: canvasWidth / 2,
            y: canvasHeight / 2,
            size: this.config.ballSize,
            dx: this.ballSpeed,
            dy: this.ballSpeed,
            color: '#FFD700'
        };

        // 重置球的位置和速度
        this.resetBall();
    }

    /**
     * 绑定事件
     */
    bindEvents() {
        // 可以在这里添加额外的事件处理
    }

    /**
     * 开始游戏
     */
    start() {
        this.isRunning = true;
        this.isPaused = false;
        this.resetBall();
    }

    /**
     * 重置游戏
     */
    reset() {
        this.player1Score = 0;
        this.player2Score = 0;
        this.roundCount = 1;
        this.ballSpeed = this.config.ballSpeed;
        this.isRunning = false;
        this.isPaused = false;

        this.initGameObjects();
    }

    /**
     * 设置暂停状态
     */
    setPaused(paused) {
        this.isPaused = paused;
    }

    /**
     * 移动玩家1
     */
    movePlayer1(direction) {
        if (this.isPaused) return;

        if (direction === 'up') {
            this.paddle1.speed = -this.config.paddleSpeed;
        } else if (direction === 'down') {
            this.paddle1.speed = this.config.paddleSpeed;
        }
    }

    /**
     * 停止玩家1
     */
    stopPlayer1() {
        this.paddle1.speed = 0;
    }

    /**
     * 移动玩家2
     */
    movePlayer2(direction) {
        if (this.isPaused) return;

        if (direction === 'up') {
            this.paddle2.speed = -this.config.paddleSpeed;
        } else if (direction === 'down') {
            this.paddle2.speed = this.config.paddleSpeed;
        }
    }

    /**
     * 停止玩家2
     */
    stopPlayer2() {
        this.paddle2.speed = 0;
    }

    /**
     * 更新游戏状态
     */
    update() {
        if (this.isPaused) return;

        this.updatePaddles();
        this.updateBall();
        this.checkCollisions();
    }

    /**
     * 更新球拍位置
     */
    updatePaddles() {
        // 更新玩家1球拍
        this.paddle1.y += this.paddle1.speed;
        this.paddle1.y = Math.max(0, Math.min(this.canvas.height - this.paddle1.height, this.paddle1.y));

        // 更新玩家2球拍
        this.paddle2.y += this.paddle2.speed;
        this.paddle2.y = Math.max(0, Math.min(this.canvas.height - this.paddle2.height, this.paddle2.y));
    }

    /**
     * 更新球的位置
     */
    updateBall() {
        this.ball.x += this.ball.dx;
        this.ball.y += this.ball.dy;

        // 检查球是否超出边界
        if (this.ball.y <= 0 || this.ball.y >= this.canvas.height - this.ball.size) {
            this.ball.dy = -this.ball.dy;
        }

        // 检查球是否超出左右边界（得分）
        if (this.ball.x <= 0) {
            this.player2Score++;
            this.handleScore();
        } else if (this.ball.x >= this.canvas.width - this.ball.size) {
            this.player1Score++;
            this.handleScore();
        }
    }

    /**
     * 检查碰撞
     */
    checkCollisions() {
        // 检查球与球拍的碰撞
        this.checkPaddleCollision(this.paddle1);
        this.checkPaddleCollision(this.paddle2);
    }

    /**
     * 检查球与球拍的碰撞
     */
    checkPaddleCollision(paddle) {
        if (this.ball.x < paddle.x + paddle.width &&
            this.ball.x + this.ball.size > paddle.x &&
            this.ball.y < paddle.y + paddle.height &&
            this.ball.y + this.ball.size > paddle.y) {

            // 碰撞发生，改变球的方向
            this.ball.dx = -this.ball.dx;

            // 根据碰撞位置调整球的垂直速度
            const hitPosition = (this.ball.y + this.ball.size / 2 - paddle.y) / paddle.height;
            this.ball.dy = (hitPosition - 0.5) * this.ballSpeed * 2;

            // 增加球速
            this.ballSpeed = Math.min(this.ballSpeed + 0.5, 15);
            this.ball.dx = this.ball.dx > 0 ? this.ballSpeed : -this.ballSpeed;
        }
    }

    /**
     * 处理得分
     */
    handleScore() {
        this.roundCount++;
        this.ballSpeed = Math.min(this.ballSpeed + 1, 15);
        this.resetBall();

        // 检查游戏是否结束
        if (this.player1Score >= this.config.maxScore || this.player2Score >= this.config.maxScore) {
            this.isRunning = false;
        }
    }

    /**
     * 重置球的位置
     */
    resetBall() {
        this.ball.x = this.canvas.width / 2;
        this.ball.y = this.canvas.height / 2;

        // 随机选择初始方向
        const direction = Math.random() > 0.5 ? 1 : -1;
        this.ball.dx = this.ballSpeed * direction;
        this.ball.dy = (Math.random() - 0.5) * this.ballSpeed;
    }

    /**
     * 检查游戏是否结束
     */
    checkGameOver() {
        return this.player1Score >= this.config.maxScore || this.player2Score >= this.config.maxScore;
    }

    /**
     * 获取获胜者
     */
    getWinner() {
        if (this.player1Score >= this.config.maxScore) {
            return '玩家1';
        } else if (this.player2Score >= this.config.maxScore) {
            return '玩家2';
        }
        return '平局';
    }

    /**
     * 处理窗口大小变化
     */
    handleResize() {
        // 重新计算球拍位置
        const canvasWidth = this.canvas.width;
        const canvasHeight = this.canvas.height;

        this.paddle1.x = 50;
        this.paddle1.y = canvasHeight / 2 - this.config.paddleHeight / 2;

        this.paddle2.x = canvasWidth - 50 - this.config.paddleWidth;
        this.paddle2.y = canvasHeight / 2 - this.config.paddleHeight / 2;

        // 重置球的位置
        this.resetBall();
    }

    /**
     * 渲染游戏
     */
    render(ctx) {
        // 绘制背景
        this.drawBackground(ctx);

        // 绘制球拍
        this.drawPaddle(ctx, this.paddle1);
        this.drawPaddle(ctx, this.paddle2);

        // 绘制球
        this.drawBall(ctx);

        // 绘制中心线
        this.drawCenterLine(ctx);

        // 绘制分数
        this.drawScore(ctx);
    }

    /**
     * 绘制背景
     */
    drawBackground(ctx) {
        ctx.fillStyle = '#000';
        ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
    }

    /**
     * 绘制球拍
     */
    drawPaddle(ctx, paddle) {
        ctx.fillStyle = paddle.color;
        ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);

        // 添加高光效果
        ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
        ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height / 2);
    }

    /**
     * 绘制球
     */
    drawBall(ctx) {
        // 绘制球的阴影
        ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
        ctx.beginPath();
        ctx.arc(this.ball.x + 2, this.ball.y + 2, this.ball.size, 0, Math.PI * 2);
        ctx.fill();

        // 绘制球
        ctx.fillStyle = this.ball.color;
        ctx.beginPath();
        ctx.arc(this.ball.x, this.ball.y, this.ball.size, 0, Math.PI * 2);
        ctx.fill();

        // 添加高光效果
        ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
        ctx.beginPath();
        ctx.arc(this.ball.x - 2, this.ball.y - 2, this.ball.size / 3, 0, Math.PI * 2);
        ctx.fill();
    }

    /**
     * 绘制中心线
     */
    drawCenterLine(ctx) {
        const centerX = this.canvas.width / 2;

        ctx.strokeStyle = '#fff';
        ctx.lineWidth = this.config.centerLineWidth;
        ctx.setLineDash([this.config.centerLineDash, this.config.centerLineDash]);
        ctx.beginPath();
        ctx.moveTo(centerX, 0);
        ctx.lineTo(centerX, this.canvas.height);
        ctx.stroke();
        ctx.setLineDash([]);
    }

    /**
     * 绘制分数
     */
    drawScore(ctx) {
        ctx.fillStyle = '#fff';
        ctx.font = '48px Arial';
        ctx.textAlign = 'center';

        // 玩家1分数
        ctx.fillText(this.player1Score.toString(), this.canvas.width / 4, 80);

        // 玩家2分数
        ctx.fillText(this.player2Score.toString(), (this.canvas.width / 4) * 3, 80);
    }
} 